/*
 * MIT License
 *
 * Copyright (c) 2023 北京凯特伟业科技有限公司
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.je.bpm.core.model.task;

import com.je.bpm.core.model.ActivitiListener;
import com.je.bpm.core.model.CustomProperty;
import com.je.bpm.core.model.FormProperty;
import com.je.bpm.core.model.ReferenceOverrider;
import java.util.*;

/**
 * 用户任务
 * <p>
 *     用于建模需要人工执行的任务。当流程执行到达用户任务时，会为指派至该任务的用户或组的任务列表创建一个新任务。
 * </p>
 */
public class UserTask extends Task {

    /**
     * 指派人
     */
    protected String assignee;
    /**
     * 拥有人
     */
    protected String owner;
    /**
     * 优先级
     */
    protected String priority;
    /**
     * 表单键
     */
    protected String formKey;
    /**
     * 到期时间
     */
    protected String dueDate;
    /**
     * 业务日历名称
     */
    protected String businessCalendarName;
    protected String category;
    protected String extensionId;
    /**
     * 候选人集合
     */
    protected List<String> candidateUsers = new ArrayList<String>();
    /**
     * 候选组集合
     */
    protected List<String> candidateGroups = new ArrayList<String>();
    /**
     * 表单属性
     */
    protected List<FormProperty> formProperties = new ArrayList<FormProperty>();
    /**
     * 任务监听
     */
    protected List<ActivitiListener> taskListeners = new ArrayList<ActivitiListener>();
    /**
     * 跳过表达式
     */
    protected String skipExpression;
    /**
     *
     */
    protected Map<String, Set<String>> customUserIdentityLinks = new HashMap<String, Set<String>>();
    /**
     *
     */
    protected Map<String, Set<String>> customGroupIdentityLinks = new HashMap<String, Set<String>>();
    /**
     * 自定义属性集合
     */
    protected List<CustomProperty> customProperties = new ArrayList<CustomProperty>();

    public String getAssignee() {
        return assignee;
    }

    public void setAssignee(String assignee) {
        this.assignee = assignee;
    }

    public String getOwner() {
        return owner;
    }

    public void setOwner(String owner) {
        this.owner = owner;
    }

    public String getPriority() {
        return priority;
    }

    public void setPriority(String priority) {
        this.priority = priority;
    }

    public String getFormKey() {
        return formKey;
    }

    public void setFormKey(String formKey) {
        this.formKey = formKey;
    }

    public String getDueDate() {
        return dueDate;
    }

    public void setDueDate(String dueDate) {
        this.dueDate = dueDate;
    }

    public String getBusinessCalendarName() {
        return businessCalendarName;
    }

    public void setBusinessCalendarName(String businessCalendarName) {
        this.businessCalendarName = businessCalendarName;
    }

    public String getCategory() {
        return category;
    }

    public void setCategory(String category) {
        this.category = category;
    }

    public String getExtensionId() {
        return extensionId;
    }

    public void setExtensionId(String extensionId) {
        this.extensionId = extensionId;
    }

    public boolean isExtended() {
        return extensionId != null && !extensionId.isEmpty();
    }

    public List<String> getCandidateUsers() {
        return candidateUsers;
    }

    public void setCandidateUsers(List<String> candidateUsers) {
        this.candidateUsers = candidateUsers;
    }

    public List<String> getCandidateGroups() {
        return candidateGroups;
    }

    public void setCandidateGroups(List<String> candidateGroups) {
        this.candidateGroups = candidateGroups;
    }

    public List<FormProperty> getFormProperties() {
        return formProperties;
    }

    public void setFormProperties(List<FormProperty> formProperties) {
        this.formProperties = formProperties;
    }

    public List<ActivitiListener> getTaskListeners() {
        return taskListeners;
    }

    public void setTaskListeners(List<ActivitiListener> taskListeners) {
        this.taskListeners = taskListeners;
    }

    public void addCustomUserIdentityLink(String userId, String type) {
        Set<String> userIdentitySet = customUserIdentityLinks.get(type);

        if (userIdentitySet == null) {
            userIdentitySet = new HashSet<String>();
            customUserIdentityLinks.put(type, userIdentitySet);
        }

        userIdentitySet.add(userId);
    }

    public void addCustomGroupIdentityLink(String groupId, String type) {
        Set<String> groupIdentitySet = customGroupIdentityLinks.get(type);

        if (groupIdentitySet == null) {
            groupIdentitySet = new HashSet<String>();
            customGroupIdentityLinks.put(type, groupIdentitySet);
        }

        groupIdentitySet.add(groupId);
    }

    public Map<String, Set<String>> getCustomUserIdentityLinks() {
        return customUserIdentityLinks;
    }

    public void setCustomUserIdentityLinks(Map<String, Set<String>> customUserIdentityLinks) {
        this.customUserIdentityLinks = customUserIdentityLinks;
    }

    public Map<String, Set<String>> getCustomGroupIdentityLinks() {
        return customGroupIdentityLinks;
    }

    public void setCustomGroupIdentityLinks(Map<String, Set<String>> customGroupIdentityLinks) {
        this.customGroupIdentityLinks = customGroupIdentityLinks;
    }

    public List<CustomProperty> getCustomProperties() {
        return customProperties;
    }

    public void setCustomProperties(List<CustomProperty> customProperties) {
        this.customProperties = customProperties;
    }

    public String getSkipExpression() {
        return skipExpression;
    }

    public void setSkipExpression(String skipExpression) {
        this.skipExpression = skipExpression;
    }

    @Override
    public UserTask clone() {
        UserTask clone = new UserTask();
        clone.setValues(this);
        return clone;
    }

    public void setValues(UserTask otherElement) {
        super.setValues(otherElement);
        setAssignee(otherElement.getAssignee());
        setOwner(otherElement.getOwner());
        setFormKey(otherElement.getFormKey());
        setDueDate(otherElement.getDueDate());
        setPriority(otherElement.getPriority());
        setCategory(otherElement.getCategory());
        setExtensionId(otherElement.getExtensionId());
        setSkipExpression(otherElement.getSkipExpression());

        setCandidateGroups(new ArrayList<String>(otherElement.getCandidateGroups()));
        setCandidateUsers(new ArrayList<String>(otherElement.getCandidateUsers()));

        setCustomGroupIdentityLinks(otherElement.customGroupIdentityLinks);
        setCustomUserIdentityLinks(otherElement.customUserIdentityLinks);

        formProperties = new ArrayList<FormProperty>();
        if (otherElement.getFormProperties() != null && !otherElement.getFormProperties().isEmpty()) {
            for (FormProperty property : otherElement.getFormProperties()) {
                formProperties.add(property.clone());
            }
        }

        taskListeners = new ArrayList<ActivitiListener>();
        if (otherElement.getTaskListeners() != null && !otherElement.getTaskListeners().isEmpty()) {
            for (ActivitiListener listener : otherElement.getTaskListeners()) {
                taskListeners.add(listener.clone());
            }
        }
    }

    @Override
    public void accept(ReferenceOverrider referenceOverrider) {
        referenceOverrider.override(this);
    }

}
